package com.mbschenkel.client;

import java.io.BufferedReader;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratedPopupPanel;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.mbschenkel.server.LatexServiceImpl;

public class FileTab extends Composite {
	private class JobQueryTimer extends Timer {
		  public String jobID = "";
		  public void run() {
				GWT.log("job query. timer called jobID="+jobID, null);
				Session.getInstance().latexService.queryJob(
						Session.getInstance().getSessionData().getSessionVerificationData(),
						jobID, new AsyncCallback<String>() 
				{
					public void onFailure(Throwable caught) {
						Window.alert("RPC to queryJob failed" + caught.getMessage() );
					}
					public void onSuccess(String result) {
						outputHTML.setHTML(result);
					}
				});
		  }
	  };
	  
	  private VerticalPanel panel = new VerticalPanel();
	  private HTML details = new HTML("File xyz details...");
	  private TextArea input = new TextArea();
	  private Button compile = new Button();
	  private Button saveBtn = new Button();
	  private Image preview = new Image();
	  private HorizontalSplitPanel split = new HorizontalSplitPanel();
	  private HTML outputHTML = new HTML("");
	  private String jobID = ""; // TODO should be part of each block...
	  
	  private JobQueryTimer jobQueryTimer = new JobQueryTimer(); 
	  
	  public FileTab() {
	      details.setHeight("50px");
		  panel.add( details );
		  split.setHeight("300px");
		  split.setWidth("100%");
		  split.setSplitPosition("70%");
		  input.setWidth("100%");
		  input.setHeight("100%");
		  input.setText("\\section{foo}\nbar $\\alpha^2 = \\int_2^4 d\\theta$."); //TODO remove
		  split.setLeftWidget( input );
		  preview.setVisible(false);
		  split.setRightWidget(preview );
		  compile.setText("compile");
		  panel.add( compile );
		  saveBtn.setText("Save");
		  panel.add( saveBtn );
		  panel.add( split );
		  outputHTML.setSize("100%","100px");

		// Add advanced options to form in a disclosure panel
		    DisclosurePanel advancedDisclosure = new DisclosurePanel("Output");
		    advancedDisclosure.setAnimationEnabled(true);
		    advancedDisclosure.setContent(outputHTML);
		    advancedDisclosure.setOpen(true);
		    outputHTML.setStyleName("mbsOutputDisclosure");
		    panel.add(advancedDisclosure);
			initWidget(panel);
			setHeight("100%");

		    
			  compile.addClickListener(new ClickListener() {
		          public void onClick(Widget sender) {
		              outputHTML.setHTML("start compiling..."); 
		        	  makeCall(input.getText());
		            }
			  });
			  
			  saveBtn.addClickListener(new ClickListener() {
		          public void onClick(Widget sender) {
		              outputHTML.setHTML("start saving..."); 
		        	  callSave("--save cmd--");
		            }
			  });
	  }
	  
	  public void setText(String s) {
		input.setText(s);  
	  }

		/**
		 * Make a GWT-RPC call to the server. The LatexService class member was
		 * initalized when the module started up.
		 */
		void makeCall(String message) {
				//final String jobID = null;
			    GWT.log("renderFull()", null);
			    
			    AsyncCallback<String> renderCallback = new AsyncCallback<String>() {
				    AsyncCallback<String> processCallback = new AsyncCallback<String>() {
				    	public void onFailure(Throwable caught) {
				    		Window.alert("RPC to processJob failed: "
								+ caught.getMessage());

				    		jobQueryTimer.run(); // run at least once at the end
						    jobQueryTimer.cancel();
				    	}
				    	public void onSuccess(String result) {
				    		GWT.log("RPC to processJob onSuccess",null);
				    		preview.setUrl("C:\\Dokumente und Einstellungen\\mbs\\Desktop\\gwt-windows-1.5.3\\gwt-windows-1.5.3\\LatexProj1\\temp\\"+jobID+"\\file.png");
				    		preview.setVisible(true);

				    		jobQueryTimer.run(); // run at least once at the end
						    jobQueryTimer.cancel();
				    	}
				    };
				    
			    	public void onFailure(Throwable caught) {
			    		Window.alert("RPC to latex renderer failed: "
							+ caught.getMessage());
			    	}
			    	public void onSuccess(String result) {
			    		GWT.log("renderFull() async onSuccess: "+result, null);
			    		jobID = result; // TODO ev not needed?!? -> update
			    		
			    		jobQueryTimer.jobID = result;
					    jobQueryTimer.run(); // run at least once at beginning
				    	jobQueryTimer.schedule(100);
				    	jobQueryTimer.scheduleRepeating(100);

					    GWT.log("processJob() "+jobID+" beeing called async.", null);
					    Session.getInstance().latexService.processJob(
					    		Session.getInstance().getSessionData().getSessionVerificationData(),
					    		jobID, processCallback );
			    	}
			    };
			    
			    Session.getInstance().latexService.renderFull(
			    		Session.getInstance().getSessionData().getSessionVerificationData(),
			    		message, renderCallback );
			    // process is then called asynchronosly
		}
		
		void callSave(String message) {
			Window.alert("not implemented at the moment");
			GWT.log("callSave()", null);
			Session.getInstance().latexService.myMethod(message, new AsyncCallback<String>() {
				public void onFailure(Throwable caught) {
					Window.alert("RPC to myMethod failed" + caught.getMessage() );
				}
				public void onSuccess(String result) {
					Window.alert("success"+result);
				}
			});
		}
}
